<?php
	/* Functions in this file */
	/**************************/

	// ClearBeam()
	// ClearBeamingFlag($flag)
	// ClearDataFlag($flag)
	// ClearSingleNoteData()
	// ClearTriplet()
	// ClearTripletFlag($flag)
	// GetDurationType()
	// GetMFCClassName()
	// GetMFCClassSchema()
	// GetPosition()
	// GetPreviousBeamDurationType()
	// HasArpeggioDown()
	// HasArpeggioUp()
	// HasFractionalBeam()
	// HasMarcato()
	// HasPickStrokeDown()
	// HasPickStrokeUp()
	// HasSforzando()
	// HasSlideIntoFromAbove()
	// HasSlideIntoFromBelow()
	// HasSlideOutOfDownwards()
	// HasSlideOutOfUpwards()
	// IsBeamEnd()
	// IsBeamingFlagSet($flag)
	// IsBeamStart()
	// IsDataFlagSet($flag)
	// IsDotted()
	// IsDoubleDotted()
	// IsMuted()
	// IsRest()
	// IsStaccato()
	// IsTied()
	// IsTripletEnd()
	// IsTripletFeel1st()
	// IsTripletFeel2nd()
	// IsTripletFlagSet($flag)
	// IsTripletMiddle()
	// IsTripletStart()
	// IsValidBeamingFlag($flag)
	// IsValidDataFlag($flag)
	// IsValidDurationType($durationType)
	// IsValidFretNumber($fretNumber)
	// IsValidPosition($position)
	// IsValidPreviousBeamDurationType($durationType)
	// IsValidStringNumber($stringNumber)
	// IsValidTripletFlag($flag)
	// SetBeamingFlag($flag)
	// SetDataFlag($flag)
	// SetDurationType($durationType)
	// SetPosition($position)
	// SetPreviousBeamDurationType($durationType)
	// SetTripletFlag($flag)
?>
<?php
	 
	 
	class RhythmSlash {
		 
		 
		// Default Constants
		const DEFAULT_POSITION = 0;
		const DEFAULT_BEAMING = 0;
		const DEFAULT_DATA = 0x00600000;
		const DEFAULT_DURATION_TYPE = 3;
		// 8th in power of 2 form
		 
		// Position Constants
		const MIN_POSITION = 0;
		const MAX_POSITION = 255;
		 
		// Single Note String Number Constants
		const MIN_SINGLE_NOTE_STRING_NUMBER = 1;
		const MAX_SINGLE_NOTE_STRING_NUMBER = 7;
		 
		// Single Note Fret Number Constants
		const MIN_SINGLE_NOTE_FRET_NUMBER = 0;
		const MAX_SINGLE_NOTE_FRET_NUMBER = 24;
		 
		 
		const previousBeamDuration8th = 0x00000001;
		const previousBeamDuration16th = 0x00000002;
		const previousBeamDurationTypeMask = 0x00000003;
		 
		const beamStart = 0x00000004;
		const beamFractional = 0x00000008;
		const beamEnd = 0x00000010;
		const beamTypeMask = 0x0000001c;
		 
		const beamingFlagsMask = 0x0000001f;
		 
		const tripletStart = 0x00000020;
		const tripletMiddle = 0x00000040;
		const tripletEnd = 0x00000080;
		const tripletMask = 0x000000e0;
		 
		 
		 
		const dotted = 0x00000001;
		const doubleDotted = 0x00000002;
		const dottedMask = 0x00000003;
		 
		const rest = 0x00000004;
		const tied = 0x00000008;
		const muted = 0x00000010;
		const staccato = 0x00000020;
		const singleNote = 0x00000040;
		 
		const pickStrokeUp = 0x00000080;
		const pickStrokeDown = 0x00000100;
		const pickStrokeMask = 0x00000180;
		 
		const arpeggioUp = 0x00000200;
		const arpeggioDown = 0x00000400;
		const arpeggioMask = 0x00000600;
		 
		const tripletFeel1st = 0x00000800;
		const tripletFeel2nd = 0x00001000;
		const tripletFeelMask = 0x00001800;
		 
		const marcato = 0x00002000;
		const sforzando = 0x00004000;
		const accentMask = 0x00006000;
		 
		const slideIntoFromAbove = 0x00008000;
		const slideIntoFromBelow = 0x00010000;
		const slideIntoMask = 0x00018000;
		 
		const slideOutOfDownwards = 0x00020000;
		const slideOutOfUpwards = 0x00040000;
		const slideOutOfMask = 0x00060000;
		 
		const dataFlagsMask = 0x0007ffff;
		 
		const durationTypeMask = 0x00e00000;
		const stringNumberMask = 0x07000000;
		const fretNumberMask = 0xf8000000;
		const singleNoteDataMask = 0xff000000;
		 
		 
		 
		protected $m_position = self::DEFAULT_POSITION;
		protected $m_beaming = self::DEFAULT_BEAMING;
		protected $m_data = self::DEFAULT_DATA;
		 
		 
		// MFC Class Functions
		 
		 
		function GetMFCClassName() {
			return "CRhythmSlash";
		}
		 
		 
		function GetMFCClassSchema() {
			return 1;
		}
		 
		// Position Functions
		 
		 
		 
		function IsValidPosition($position) {
			return (($position >= self::MIN_POSITION) && ($position <= self::MAX_POSITION));
		}
		 
		 
		 
		function SetPosition($position) {
			if (!$this->IsValidPosition($position)) return 0;
			$this->m_position = $position;
			 return 1;
		}
		 
		 
		function GetPosition() {
			return ($this->m_position);
		}
		 
		// Duration Type Functions
		 
		 
		 
		function IsValidDurationType($durationType) {
			return (($durationType == 1) || ($durationType == 2) || ($durationType == 4) || ($durationType == 8) || ($durationType == 16));
		}
		 
		// Previous Beam Duration Functions
		 
		 
		 
		function IsValidPreviousBeamDurationType($durationType) {
			return (($durationType == 0) || ($durationType == 8) || ($durationType == 16));
		}
		 
		 
		function SetBeamStart($set = 1) {
			if (!$set) return ($this->ClearBeamingFlag(self::beamStart));
				 return ($this->SetBeamingFlag(self::beamStart));
		}
		 
		 
		function IsBeamStart() {
			return ($this->IsBeamingFlagSet(self::beamStart));
		}
		 
		 
		 
		function SetFractionalBeam($set = 1) {
			if (!$set) return ($this->ClearBeamingFlag(self::beamFractional));
				 return ($this->SetBeamingFlag(self::beamFractional));
		}
		 
		 
		function HasFractionalBeam() {
			return ($this->IsBeamingFlagSet(self::beamFractional));
		}
		 
		 
		 
		function SetBeamEnd($set = 1) {
			if (!$set) return ($this->ClearBeamingFlag(self::beamEnd));
				 return ($this->SetBeamingFlag(self::beamEnd));
		}
		 
		 
		function IsBeamEnd() {
			return ($this->IsBeamingFlagSet(self::beamEnd));
		}
		 
		 
		function ClearBeam() {
			return ($this->ClearBeamingFlag(self::beamingFlagsMask));
		}
		 
		 
		 
		 
		 
		function IsValidBeamingFlag($flag) {
			return ((($flag & self::beamingFlagsMask) != 0) && (($flag & ~self::beamingFlagsMask) == 0));
		}
		 
		 
		function ClearBeamingFlag($flag) {
			if (!$this->IsValidBeamingFlag($flag)) return 0;
			$this->m_beaming &= ~$flag;
			 return 1;
		}
		 
		 
		 
		function IsBeamingFlagSet($flag) {
			if (!$this->IsValidBeamingFlag($flag)) return 0;
			 return (($this->m_beaming & $flag) == $flag);
		}
		 
		// Triplet Functions
		 
		 
		 
		function SetTripletStart($set = 1) {
			if (!$set) return ($this->ClearTripletFlag(self::tripletStart));
				 return ($this->SetTripletFlag(self::tripletStart));
		}
		 
		 
		function IsTripletStart() {
			return ($this->IsTripletFlagSet(self::tripletStart));
		}
		 
		 
		 
		function SetTripletMiddle($set = 1) {
			if (!$set) return ($this->ClearTripletFlag(self::tripletMiddle));
				 return ($this->SetTripletFlag(self::tripletMiddle));
		}
		 
		 
		function IsTripletMiddle() {
			return ($this->IsTripletFlagSet(self::tripletMiddle));
		}
		 
		 
		 
		function SetTripletEnd($set = 1) {
			if (!$set) return ($this->ClearTripletFlag(self::tripletEnd));
				 return ($this->SetTripletFlag(self::tripletEnd));
		}
		 
		 
		function IsTripletEnd() {
			return ($this->IsTripletFlagSet(self::tripletEnd));
		}
		 
		 
		function ClearTriplet() {
			return ($this->ClearTripletFlag(self::tripletMask));
		}
		 
		 
		 
		 
		 
		function IsValidTripletFlag($flag) {
			return ((($flag & self::tripletMask) != 0) && (($flag & ~self::tripletMask) == 0));
		}
		 
		 
		function ClearTripletFlag($flag) {
			if (!$this->IsValidTripletFlag($flag)) return 0;
			$this->m_beaming &= ~$flag;
			 return 1;
		}
		 
		 
		 
		function IsTripletFlagSet($flag) {
			if (!$this->IsValidTripletFlag($flag)) return 0;
			 return (($this->m_beaming & $flag) == $flag);
		}
		 
		// Dotted Functions
		 
		 
		 
		function SetDotted($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::dotted));
				 return ($this->SetDataFlag(self::dotted));
		}
		 
		 
		function IsDotted() {
			return ($this->IsDataFlagSet(self::dotted));
		}
		 
		// Double Dotted Functions
		 
		 
		 
		function SetDoubleDotted($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::doubleDotted));
				 return ($this->SetDataFlag(self::doubleDotted));
		}
		 
		 
		function IsDoubleDotted() {
			return ($this->IsDataFlagSet(self::doubleDotted));
		}
		 
		// Rest Functions
		 
		 
		 
		function SetRest($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::rest));
				 return ($this->SetDataFlag(self::rest));
		}
		 
		 
		function IsRest() {
			return ($this->IsDataFlagSet(self::rest));
		}
		 
		// Tied Functions
		 
		 
		 
		function SetTied($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::tied));
				 return ($this->SetDataFlag(self::tied));
		}
		 
		 
		function IsTied() {
			return ($this->IsDataFlagSet(self::tied));
		}
		 
		// Muted Functions
		 
		 
		 
		function SetMuted($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::muted));
				 return ($this->SetDataFlag(self::muted));
		}
		 
		 
		function IsMuted() {
			return ($this->IsDataFlagSet(self::muted));
		}
		 
		// Staccato Functions
		 
		 
		 
		function SetStaccato($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::staccato));
				 return ($this->SetDataFlag(self::staccato));
		}
		 
		 
		function IsStaccato() {
			return ($this->IsDataFlagSet(self::staccato));
		}
		 
		// Pick Stroke Up Functions
		 
		 
		 
		function SetPickStrokeUp($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::pickStrokeUp));
				 return ($this->SetDataFlag(self::pickStrokeUp));
		}
		 
		 
		function HasPickStrokeUp() {
			return ($this->IsDataFlagSet(self::pickStrokeUp));
		}
		 
		// Pick Stroke Down Functions
		 
		 
		 
		function SetPickStrokeDown($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::pickStrokeDown));
				 return ($this->SetDataFlag(self::pickStrokeDown));
		}
		 
		 
		function HasPickStrokeDown() {
			return ($this->IsDataFlagSet(self::pickStrokeDown));
		}
		 
		// Arpeggio Up Functions
		 
		 
		 
		function SetArpeggioUp($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::arpeggioUp));
				 return ($this->SetDataFlag(self::arpeggioUp));
		}
		 
		 
		function HasArpeggioUp() {
			return ($this->IsDataFlagSet(self::arpeggioUp));
		}
		 
		// Arpeggio Down Functions
		 
		 
		 
		function SetArpeggioDown($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::arpeggioDown));
				 return ($this->SetDataFlag(self::arpeggioDown));
		}
		 
		 
		function HasArpeggioDown() {
			return ($this->IsDataFlagSet(self::arpeggioDown));
		}
		 
		// Triplet Feel 1st Functions
		 
		 
		 
		function SetTripletFeel1st($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::tripletFeel1st));
				 return ($this->SetDataFlag(self::tripletFeel1st));
		}
		 
		 
		function IsTripletFeel1st() {
			return ($this->IsDataFlagSet(self::tripletFeel1st));
		}
		 
		// Triplet Feel 2nd Functions
		 
		 
		 
		function SetTripletFeel2nd($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::tripletFeel2nd));
				 return ($this->SetDataFlag(self::tripletFeel2nd));
		}
		 
		 
		function IsTripletFeel2nd() {
			return ($this->IsDataFlagSet(self::tripletFeel2nd));
		}
		 
		// Marcato Functions
		 
		 
		 
		function SetMarcato($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::marcato));
				 return ($this->SetDataFlag(self::marcato));
		}
		 
		 
		function HasMarcato() {
			return ($this->IsDataFlagSet(self::marcato));
		}
		 
		// Sforzando Functions
		 
		 
		 
		function SetSforzando($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::sforzando));
				 return ($this->SetDataFlag(self::sforzando));
		}
		 
		 
		function HasSforzando() {
			return ($this->IsDataFlagSet(self::sforzando));
		}
		 
		// Slide Into From Above Functions
		 
		 
		 
		function SetSlideIntoFromAbove($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::slideIntoFromAbove));
				 return ($this->SetDataFlag(self::slideIntoFromAbove));
		}
		 
		 
		function HasSlideIntoFromAbove() {
			return ($this->IsDataFlagSet(self::slideIntoFromAbove));
		}
		 
		// Slide Into From Below Functions
		 
		 
		 
		function SetSlideIntoFromBelow($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::slideIntoFromBelow));
				 return ($this->SetDataFlag(self::slideIntoFromBelow));
		}
		 
		 
		function HasSlideIntoFromBelow() {
			return ($this->IsDataFlagSet(self::slideIntoFromBelow));
		}
		 
		// Slide Out Of Downwards Functions
		 
		 
		 
		function SetSlideOutOfDownwards($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::slideOutOfDownwards));
				 return ($this->SetDataFlag(self::slideOutOfDownwards));
		}
		 
		 
		function HasSlideOutOfDownwards() {
			return ($this->IsDataFlagSet(self::slideOutOfDownwards));
		}
		 
		// Slide Out Of Upwards Functions
		 
		 
		 
		function SetSlideOutOfUpwards($set = 1) {
			if (!$set) return ($this->ClearDataFlag(self::slideOutOfUpwards));
				 return ($this->SetDataFlag(self::slideOutOfUpwards));
		}
		 
		 
		function HasSlideOutOfUpwards() {
			return ($this->IsDataFlagSet(self::slideOutOfUpwards));
		}
		 
		 
		// Flag Functions
		 
		 
		 
		function IsValidDataFlag($flag) {
			return ((($flag & self::dataFlagsMask) != 0) && (($flag & ~self::dataFlagsMask) == 0));
		}
		 
		 
		function ClearDataFlag($flag) {
			if (!$this->IsValidDataFlag($flag)) return 0;
			$this->m_data &= ~$flag;
			 return 1;
		}
		 
		 
		 
		function IsDataFlagSet($flag) {
			if (!$this->IsValidDataFlag($flag)) return 0;
			 return (($this->m_data & $flag) == $flag);
		}
		 
		 
		function IsValidStringNumber($stringNumber) {
			return (($stringNumber >= self::MIN_SINGLE_NOTE_STRING_NUMBER) && ($stringNumber <= self::MAX_SINGLE_NOTE_STRING_NUMBER));
		}
		 
		 
		 
		function IsValidFretNumber($fretNumber) {
			return (($fretNumber >= self::MIN_SINGLE_NOTE_FRET_NUMBER) && ($fretNumber <= self::MAX_SINGLE_NOTE_FRET_NUMBER));
		}
		 
		 
		 
		 
		function RhythmSlash($position=NULL, $durationType=NULL, $dotCount=NULL) {
			 
			//------Last Checked------//
			// - Jan 7, 2005
			if (!$this->IsValidPosition($position)) return 0;
			 
			$this->SetDurationType($durationType);
			if ($dotCount == 1)
				$this->SetDotted();
			else if ($dotCount == 2)
			$this->SetDoubleDotted();
		}
		 
		// Serialization functions
		 
		 
		 
		function DoSerialize(&$stream){
		 
		
			WRITE_BYTE ($stream,$this->m_position);
			WRITE_BYTE ($stream,$this->m_beaming);
			WRITE_INTEGER ($stream,$this->m_data);

			return 1;
		}
		
		 
		 
		function DoDeserialize(&$stream){
		 
			$this->m_position = READ_BYTE ($stream);
			$this->m_beaming = READ_BYTE ($stream);
			$this->m_data = READ_INTEGER ($stream);
		
		}
		
		// Duration Type Functions
		 
		 
		 
		function SetDurationType($durationType) {
			 
			//------Last Checked------//
			// - Jan 6, 2005
			if (!$this->IsValidDurationType($durationType)) return 0;
			 
			// Duration type is stored in power of two format
			$this->m_data &= ~self::durationTypeMask;
			 
			if ($durationType == 1)
				$durationType = 0;
			else if ($durationType == 2)
			$durationType = 1;
			else if ($durationType == 4)
			$durationType = 2;
			else if ($durationType == 8)
			$durationType = 3;
			else if ($durationType == 16)
			$durationType = 4;
			 
			$this->m_data |= ($durationType << 21);
			 
			return 1;
		}
		 
		 
		 
		function GetDurationType() {
			 
			//------Last Checked------//
			// - Jan 6, 2005
			$temp = (($this->m_data & self::durationTypeMask) >> 21);
			// Duration type is stored in power of two form
			return ((pow(2, $temp)));
		}
		 
		// Previous Beam Duration Functions
		 
		 
		 
		function SetPreviousBeamDurationType($durationType) {
			 
			//------Last Checked------//
			// - Jan 7, 2005
			if (!$this->IsValidPreviousBeamDurationType($durationType)) return 0;
			 
			// Clear the current duration type
			$this->m_beaming &= ~self::previousBeamDurationTypeMask;
			 
			if ($durationType == 8)
				$this->m_beaming |= self::previousBeamDuration8th;
			else if ($durationType == 16)
			$this->m_beaming |= self::previousBeamDuration16th;
			 
			return 1;
		}
		 
		 
		 
		function GetPreviousBeamDurationType() {
			 
			//------Last Checked------//
			// - Jan 7, 2005
			 
			if (($this->m_beaming & self::previousBeamDuration8th) == self::previousBeamDuration8th)
				return (8);
			else if (($this->m_beaming & self::previousBeamDuration16th) == self::previousBeamDuration16th)
			return (16);
			return (0);
		}
		 
		// Beaming Functions
		 
		 
		 
		function SetBeamingFlag($flag) {
			 
			//------Last Checked------//
			// - Jan 7, 2005
			if (!$this->IsValidBeamingFlag($flag)) return 0;
			 
			// Mutually exclusive operations
			if (($flag & self::beamStart) == self::beamStart) {
				 
				$this->ClearBeamingFlag(self::beamEnd);
				$flag &= ~self::beamEnd;
			}
			else if (($flag & self::beamEnd) == self::beamEnd)
			$this->ClearBeamingFlag(self::beamStart);
			 
			$this->m_beaming |= $flag;
			 
			return 1;
		}
		 
		// Triplet Flag Functions
		 
		 
		 
		function SetTripletFlag($flag) {
			 
			//------Last Checked------//
			// - Jan 6, 2005
			if (!$this->IsValidTripletFlag($flag)) return 0;
			 
			// Clear any current triplet $flags
			$this->ClearTripletFlag(self::tripletMask);
			 
			// Mutually exclusive operations
			if (($flag & self::tripletStart) == self::tripletStart)
				$flag = self::tripletStart;
			else if (($flag & self::tripletMiddle) == self::tripletMiddle)
			$flag = self::tripletMiddle;
			else if (($flag & self::tripletEnd) == self::tripletEnd)
			$flag = self::tripletEnd;
			 
			$this->m_beaming |= $flag;
			 
			return 1;
		}
		 
		// Data Flag Functions
		 
		 
		 
		function SetDataFlag($flag) {
			 
			//------Last Checked------//
			// - Jan 7, 2005
			if (!$this->IsValidDataFlag($flag)) return 0;
			 
			// Mutually exclusive operations
			if (($flag & self::dottedMask) != 0)
				$this->ClearDataFlag(self::dottedMask);
			 
			if (($flag & self::pickStrokeMask) != 0)
				$this->ClearDataFlag(self::pickStrokeMask);
			 
			if (($flag & self::arpeggioMask) != 0)
				$this->ClearDataFlag(self::arpeggioMask);
			 
			if (($flag & self::tripletFeelMask) != 0)
				$this->ClearDataFlag(self::tripletFeelMask);
			 
			if (($flag & self::accentMask) != 0)
				$this->ClearDataFlag(self::accentMask);
			 
			if (($flag & self::slideIntoMask) != 0)
				$this->ClearDataFlag(self::slideIntoMask);
			 
			if (($flag & self::slideOutOfMask) != 0)
				$this->ClearDataFlag(self::slideOutOfMask);
			 
			$this->m_data |= $flag;
			 
			return 1;
		}
		 
		// Single Note Data Functions
		 
		 
		 
		 
		function SetSingleNoteData($stringNumber, $fretNumber) {
			 
			//------Last Checked------//
			// - Jan 6, 2005
			if (!$this->IsValidStringNumber($stringNumber)) return 0;
			if (!$this->IsValidFretNumber($fretNumber)) return 0;
			 
			if (!$this->SetDataFlag(self::singleNote))
				return 0;
			 
			$this->m_data &= ~self::singleNoteDataMask;
			$this->m_data |= ($stringNumber << 24);
			$this->m_data |= ($fretNumber << 27);
			 
			return 1;
		}
		 
		 
		 
		 
		function GetSingleNoteData(&$stringNumber, &$fretNumber) {
			 
			//------Last Checked------//
			// - Jan 6, 2005
			$stringNumber = (($this->m_data & self::stringNumberMask) >> 24);
			$fretNumber = (($this->m_data & self::fretNumberMask) >> 27);
		}
		 
		 
		 
		function ClearSingleNoteData() {
			 
			//------Last Checked------//
			// - Jan 7, 2005
			if (!$this->ClearDataFlag(self::singleNote))
				return 0;
			 
			$this->m_data &= ~self::singleNoteDataMask;
			 
			return 1;
		}
		 
		 
	}
	 
?>

